// Name: Hook
// Description: Hooking related methods.
// Author: kartu
//
// History:
//	2010-03-14 kartu - Initial version, refactored from Utils

Core.hook = {};

// Constants
var CORE_HOOK_BEFORE = 0;
var CORE_HOOK_INSTEAD = 1;
var CORE_HOOK_AFTER = 2;

var core_hook_doHook = function (where, what, oldFunc, newFunc, hookType, tag) {
	if(typeof where[what] !== "function" && hookType !== CORE_HOOK_INSTEAD) {
		log.error("cannot hook before/after non-existing function: " + what);
		return;
	}
	switch(hookType) {
	case CORE_HOOK_BEFORE:
		where[what] = function() {
			try {
				newFunc.call(this, arguments, oldFunc, tag);
			} catch(ignore) {
			}
			oldFunc.apply(this, arguments);
		};
		break;
	case CORE_HOOK_AFTER:
		where[what] = function() {
			oldFunc.apply(this, arguments);
			try {
				newFunc.call(this, arguments, oldFunc, tag);
			} catch (ignore) {
			}
		};
		break;
	case CORE_HOOK_INSTEAD:
		where[what] = function() {
			newFunc.call(this, arguments, oldFunc, tag);
		};
		break;
	default:
		log.error("unknown hook type: " + hookType);
	}
	
};
Core.hook.hook = function(where, what, newFunction, tag) {
	core_hook_doHook(where, what, where[what], newFunction, CORE_HOOK_INSTEAD, tag);
};
Core.hook.hookBefore = function(where, what, newFunction, tag) {
	core_hook_doHook(where, what, where[what], newFunction, CORE_HOOK_BEFORE, tag);
};
Core.hook.hookAfter = function(where, what, newFunction, tag) {
	core_hook_doHook(where, what, where[what], newFunction, CORE_HOOK_AFTER, tag);
};
